from rest_framework import serializers
from .models import Order, OrderDetail
from course.models import Course
import uuid
from rest_framework.exceptions import ValidationError
from luffyapi.libs.alpay import settings as pay_settings
from django.conf import settings


class OrderModelSerializer(serializers.ModelSerializer):
    # courses:[1,2,3]
    # 转换成courses:[obj1,obj2,obj3]
    courses = serializers.PrimaryKeyRelatedField(queryset=Course.objects.all(), many=True)

    class Meta:
        model = Order
        fields = [
            'courses',
            'subject',
            'pay_type',
            'total_amount'
        ]

    def _check_money(self, attrs):
        # 校验钱是否合法
        total_amount = attrs.get('total_amount')
        total = 0
        for course in attrs.get('courses'):
            total += course.price
        if total_amount == total:
            return total_amount
        else:
            raise ValidationError('钱不对')

    def _get_trade_no(self):
        trade_no = str(uuid.uuid4()).replace('-', '')
        return trade_no

    def _get_user(self):
        return self.context['request'].user

    def _get_pay_url(self, subject, trade_no, total_amount):
        from luffyapi.libs.alpay import alipay

        res = alipay.api_alipay_trade_page_pay(
            subject=subject,
            out_trade_no=trade_no,
            total_amount=float(total_amount),  # 转成float类型
            return_url=settings.RETURN_URL,
            notify_url=settings.NOTIFY_URL
        )

        pay_url = pay_settings.GATEWAY + res  # 支付链接
        self.context['pay_url'] = pay_url

    def _pre_model(self, attrs, user, total_amount, trade_no):
        attrs['user'] = user
        attrs['total_amount'] = total_amount
        attrs['out_trade_no'] = trade_no
        # courses需要pop出来，但是不着急

    def validate(self, attrs):
        # -校验钱是否正确
        total_amount = self._check_money(attrs)
        # -生成订单号（uuid，分布式id的生成）
        trade_no = self._get_trade_no()
        # -获取当前登录用户（request.user）
        user = self._get_user()
        # -生成支付链接（context）
        self._get_pay_url(attrs['subject'], trade_no, total_amount)
        # -入库前准备（把user，订单号放到字典中）
        self._pre_model(attrs, user, total_amount, trade_no)
        return attrs

    def create(self, validated_data):
        courses = validated_data.pop('courses')
        # 存订单表
        order = Order.objects.create(**validated_data)

        # 存订单详情表
        for course in courses:
            OrderDetail.objects.create(order=order, course=course, price=course.price, real_price=course.price)

        return order
